{
 "cells": [
  {
   "metadata": {},
   "cell_type": "raw",
   "source": [
    "ChatPromptTemplate的使用\n",
    "1，两种实现方式\n",
    "1.1，使用构造方法\n",
    "1.2，使用from_messages()方法\n",
    "\n",
    "2,几种不同的调用方式\n",
    "format()\\invoke()\\format_messages()\\format_prompt()\n",
    "2.1，format():传入的是一个个的变量，返回字符串类型\n",
    "2.2，invoke():传入的是一个字典，返回的是ChatPromptValue类型\n",
    "2.3，format_messages():传入的是一个个的变量，返回一个list[Message] ---推荐的写法\n",
    "2.4，format_prompt():传入的是一个个的变量，返回一个ChatPromptValue类型\n",
    "\n",
    "\n",
    "3，几种不同类型的参数情况\n",
    "形参列表的类型 ，除了可以是元组构成的列表以外，可以是：\n",
    "通过源码发现，形参列表的类型，除了元组构成的列表以外，还可以是：\n",
    "\n",
    "字符串、字典、列表类型、消息类型、ChatPromptTemplate【分两种 带参数和不同参数】、BaseMessagePromptTemplate等构成的列表\n",
    "\n",
    "① 字符串类型。此时的字符串看作是HumanMessage的content\n",
    "\n",
    "2，ChatPromptTemplate【分两种 带参数和不同参数】\n",
    "⑤ BaseMessagePromptTemplate\n",
    "\n",
    "具体的体现：SystemMessagePromptTemplate、HumanMessagePromptTemplate、AIMessagePromptTemplate ; ChatMessagePromptTemplate\n",
    "\n"
   ],
   "id": "a1c52566d55b23f5"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 结合大模型的调用",
   "id": "bdb72ce1b7446aee"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-02T06:30:51.793836Z",
     "start_time": "2025-08-02T06:30:47.225202Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import os\n",
    "import dotenv\n",
    "from langchain_community.chat_models import ChatOpenAI\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "\n",
    "dotenv.load_dotenv()\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\")\n",
    "os.environ[\"OPENAI_BASE_URL\"] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "\n",
    "\n",
    "# 1,获取大模型\n",
    "chat_model = ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "\n",
    "#2，提供提示词\n",
    "#2.1提供提示词的模板\n",
    "chat_prompt = ChatPromptTemplate.from_messages([\n",
    "\n",
    "    (\"system\", \"你是一个数学家，可以做任何计算\"),\n",
    "    (\"human\", '{text}')\n",
    "])\n",
    "\n",
    "#2.2调用提示词模板的方法，返回不带变量的结果\n",
    "\n",
    "messages = chat_prompt.invoke({\"text\": \"我今年18岁，我的舅舅今年38岁，我的爷爷今年72岁，我和舅舅一共多少岁了？\"})\n",
    "\n",
    "#2.3通过大模型调用invoke()\n",
    "chat_model.invoke(messages)"
   ],
   "id": "78af4d917fd0d51",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='你和舅舅的年龄加起来是：\\n\\n你的年龄：18岁  \\n舅舅的年龄：38岁  \\n\\n总和 = 18 + 38 = 56岁\\n\\n所以，你和舅舅一共56岁。', additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 53, 'prompt_tokens': 52, 'total_tokens': 105, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_34a54ae93c', 'finish_reason': 'stop', 'logprobs': None}, id='run--4abee3cb-9bb3-424a-bc57-eed26e92abc8-0')"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 18
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## chain=chat_prompt | chat_model  方式",
   "id": "5af78abcc08a36dc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-02T06:32:35.550309Z",
     "start_time": "2025-08-02T06:32:31.984301Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import os\n",
    "import dotenv\n",
    "from langchain_community.chat_models import ChatOpenAI\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "\n",
    "dotenv.load_dotenv()\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\")\n",
    "os.environ[\"OPENAI_BASE_URL\"] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "\n",
    "\n",
    "# 1,获取大模型\n",
    "chat_model = ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "\n",
    "#2，提供提示词\n",
    "#2.1提供提示词的模板\n",
    "chat_prompt = ChatPromptTemplate.from_messages([\n",
    "\n",
    "    (\"system\", \"你是一个数学家，可以做任何计算\"),\n",
    "    (\"human\", '{text}')\n",
    "])\n",
    "\n",
    "\n",
    "chain=chat_prompt | chat_model\n",
    "chain.invoke({\"text\": \"我今年18岁，我的舅舅今年38岁，我的爷爷今年72岁，我和舅舅一共多少岁了？\"})\n"
   ],
   "id": "47660aa279aa9c57",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='你的年龄是18岁，你舅舅的年龄是38岁。你和你舅舅的年龄总和是：\\n\\n18 + 38 = 56\\n\\n所以你和舅舅一共56岁。', additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 49, 'prompt_tokens': 52, 'total_tokens': 101, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_34a54ae93c', 'finish_reason': 'stop', 'logprobs': None}, id='run--05135164-2f99-4b55-98c9-e9120ed2313f-0')"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 19
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# MessagesPlaceholder的使用\n",
    "\n",
    "##### 当你不确定消息提示模板使用什么角色的，或者希望在格式化过程中 插入消息列表时，该怎么办？\n",
    "这就需要使用MessagesPlaceholder，负责在特定位置添加消息列表"
   ],
   "id": "b9318b9f660f7b04"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-02T09:22:41.554823Z",
     "start_time": "2025-08-02T09:22:41.539308Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.messages import HumanMessage,SystemMessage\n",
    "from langchain_core.prompts import MessagesPlaceholder,ChatPromptTemplate\n",
    "\n",
    "\n",
    "prompt_template=ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"你是一个wuli家，可以做任何计算\"),\n",
    "    MessagesPlaceholder(variable_name=\"history\")\n",
    "\n",
    "\n",
    "])\n",
    "prompt_template.format_messages(history=[\n",
    "    SystemMessage(content=\"你是一个数学家，可以做任何计算\"),\n",
    "    HumanMessage(content=\"我今年18岁，我的舅舅今年38岁，我的爷爷今年72岁，我和舅舅一共多少岁了？\")\n",
    "],area='天文学'\n",
    ")"
   ],
   "id": "e6df8eb0df0a3b22",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[SystemMessage(content='你是一个wuli家，可以做任何计算', additional_kwargs={}, response_metadata={}),\n",
       " SystemMessage(content='你是一个数学家，可以做任何计算', additional_kwargs={}, response_metadata={}),\n",
       " HumanMessage(content='我今年18岁，我的舅舅今年38岁，我的爷爷今年72岁，我和舅舅一共多少岁了？', additional_kwargs={}, response_metadata={})]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 23
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-02T09:37:09.725791Z",
     "start_time": "2025-08-02T09:37:05.893656Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.messages import HumanMessage,SystemMessage\n",
    "from langchain_core.prompts import MessagesPlaceholder,ChatPromptTemplate\n",
    "\n",
    "\n",
    "dotenv.load_dotenv()\n",
    "\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv(\"OPENAI_API_KEY\")\n",
    "os.environ['OPENAI_BASE_URL'] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "\n",
    "chat_model = ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "\n",
    "\n",
    "\n",
    "prompt_template=ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"你是一个wuli家，可以做任何计算\"),\n",
    "    MessagesPlaceholder(variable_name=\"history\")\n",
    "\n",
    "\n",
    "])\n",
    "messages=prompt_template.format_messages(history=[\n",
    "    SystemMessage(content=\"你是一个数学家，可以做任何计算\"),\n",
    "    HumanMessage(content=\"我今年18岁，我的舅舅今年38岁，我的爷爷今年72岁，我和舅舅一共多少岁了？\")\n",
    "],area='天文学'\n",
    ")\n",
    "\n",
    "\n",
    "chat_model.invoke(messages)"
   ],
   "id": "b89415ab6899133b",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='你今年18岁，你的舅舅今年38岁。要计算你和舅舅一共多少岁，可以将你们的年龄相加：\\n\\n18 + 38 = 56\\n\\n所以，你和舅舅一共56岁。', additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 55, 'prompt_tokens': 66, 'total_tokens': 121, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_34a54ae93c', 'finish_reason': 'stop', 'logprobs': None}, id='run--f792a93d-b218-49f1-97f4-d594d3c5a539-0')"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 30
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
